﻿using System;
using System.Collections.Generic;
using System.Web;
using HashMaster.Lib;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.IO;


namespace HashMaster.Service
{
    public static class Utility
    {
        private static string ConnStr = ConfigurationManager.ConnectionStrings["LocalConnStr"].ConnectionString;

        #region Client

        /// <summary>
        /// 禁用客户端收回任务
        /// </summary>
        /// <param name="jobId"></param>
        internal static int RetrieveJob(ClientSyncData clientData)
        {
            int ret = 0;
            try
            {
                using (SqlConnection conn = new SqlConnection(ConnStr))
                {
                    using (SqlCommand cmd = new SqlCommand("RetrieveJob", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@clientName", clientData.ClientName);
                        cmd.Parameters.AddWithValue("@macAddress", clientData.MacAddress);
                        cmd.Parameters.Add("@RetVal", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;

                        conn.Open();
                        cmd.ExecuteNonQuery();

                        ret = (int)cmd.Parameters["@RetVal"].Value;
                    }
                }
            }
            catch (Exception ex)
            {

                SaveErrorMessage("\r\nRetrieveJob \r\n" + ex.Message);
            }
            return ret;
        }

        /// <summary>
        /// 获取所有未禁用客户机
        /// </summary>
        /// <returns></returns>
        internal static List<Client> GetAllClients()
        {
            List<Client> ret = new List<Client>();

            try
            {
                using (SqlConnection conn = new SqlConnection(ConnStr))
                {
                    using (SqlCommand cmd = new SqlCommand("GetAllClients", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;

                        conn.Open();
                        SqlDataReader reader = cmd.ExecuteReader();
                        while (reader.Read())
                        {
                            Client client = new Client();
                            client.ClientName = reader["ClientName"].ToString();
                            client.MacAddress = reader["MacAddress"].ToString();
                            client.LastActive = (DateTime)reader["LastActive"];
                            client.Status = (EnumStatus)reader["StatusId"];
                            ret.Add(client);
                        }
                    }
                }
            }
            catch (SqlException ex)
            {
                SaveErrorMessage("\r\nGetAllClients \r\n" + ex.Message);
            }

            return ret;

        }

        #endregion

        #region Task
        /// <summary>
        /// 新增任务
        /// </summary>
        /// <param name="imei"></param>
        /// <param name="sha"></param>
        /// <param name="sliceWidth"></param>
        /// <returns></returns>
        internal static bool AddNewTask(Task task)
        {
            //ClientSyncData ret = new ClientSyncData() ;
            //ret.ErrorCode = 102;
            bool ret = false;
            try
            {
                using (SqlConnection conn = new SqlConnection(ConnStr))
                {
                    using (SqlCommand cmd = new SqlCommand("AddNewTask", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@imei", task.Imei);
                        cmd.Parameters.AddWithValue("@sha", task.Sha);
                        cmd.Parameters.AddWithValue("@sliceWidth", task.SliceWidth);
                        cmd.Parameters.Add("@RetVal", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;

                        conn.Open();
                        cmd.ExecuteNonQuery();
                        ret = (int)cmd.Parameters["@RetVal"].Value == 0 ? true : false;
                        //ret.ErrorCode = (int)cmd.Parameters["@RetVal"].Value == 0 ? 0 : 101;

                    }
                }
            }
            catch (SqlException ex)
            {

                SaveErrorMessage("\r\nAddNewTask \r\n" + ex.Message);
            }
            return ret;
        }

        /// <summary>
        /// 修改任务信息
        /// </summary>
        /// <param name="task"></param>
        /// <returns></returns>
        internal static bool ModifyTask(string imei,int priority=99,string memo="Empty",bool extracted=false)
        {
            bool ret = false;
            try
            {
                using (SqlConnection conn = new SqlConnection(ConnStr))
                {
                    using (SqlCommand cmd = new SqlCommand("ModifyTask", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@imei", imei);
                        cmd.Parameters.AddWithValue("@priority", priority);
                        cmd.Parameters.AddWithValue("@memo", memo);
                        cmd.Parameters.AddWithValue("@extracted", extracted);
                        
                        cmd.Parameters.Add("@RetVal", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;

                        conn.Open();
                        cmd.ExecuteNonQuery();
                        ret = (int)cmd.Parameters["@RetVal"].Value == 0 ? false : true;

                    }
                }
            }
            catch (SqlException ex)
            {

                SaveErrorMessage("\r\nModifyTask \r\n" + ex.Message);
            }
            return ret;
        }

        /// <summary>
        /// 获取所有任务信息
        /// </summary>
        /// <returns></returns>
        internal static List<Task> GetAvailableTasts()
        {
            List<Task> tasks = new List<Task>();
            try
            {
                using (SqlConnection conn = new SqlConnection(ConnStr))
                {
                    using (SqlCommand cmd = new SqlCommand("GetAvailableTasts", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        conn.Open();
                        SqlDataReader reader = cmd.ExecuteReader();

                        while (reader.Read())
                        {
                            Task task = new Task
                            {
                                Priority = (int)reader["Priority"],
                                Imei = reader["Imei"].ToString(),
                                StatusId = (int)reader["StatusId"],
                                Memo = reader["Memo"].ToString(),
                                Progress = reader["Progress"].ToString(),
                                Result = reader["Result"].ToString(),
                            };
                            tasks.Add(task);
                        }

                    }
                }
            }
            catch (SqlException ex)
            {
                SaveErrorMessage("\r\nGetAllTasks \r\n" + ex.Message);
            }
            return tasks;
        }

        internal static List<Task> GetExtractableTasks()
        {
            List<Task> tasks = new List<Task>();
            try
            {
                using (SqlConnection conn = new SqlConnection(ConnStr))
                {
                    using (SqlCommand cmd = new SqlCommand("GetExtractableTasks", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        conn.Open();
                        SqlDataReader reader = cmd.ExecuteReader();
                        while (reader.Read())
                        {
                            Task task = new Task
                            {
                                //Priority = (int)reader["Priority"],
                                Imei = reader["Imei"].ToString(),
                                //StatusId = (int)reader["StatusId"],
                                //Memo = reader["Memo"].ToString(),
                                //Progress = reader["Progress"].ToString(),
                                Result = reader["Result"].ToString(),
                            };
                            tasks.Add(task);
                        }

                    }
                }
            }
            catch (SqlException ex)
            {
                SaveErrorMessage("\r\nGetAllTasks \r\n" + ex.Message);
            }
            return tasks;
        }
        #endregion

        #region Job
        /// <summary>
        /// 客户端获取任务，有任务时直接返回，没任务时分配后返回
        /// </summary>
        /// <param name="clientName"></param>
        /// <param name="macAddress"></param>
        /// <returns></returns>
        internal static ClientSyncData GetJobByClient(ClientSyncData clientData)
        {
            ClientSyncData ret = new ClientSyncData();
            try
            {
                using (SqlConnection conn = new SqlConnection(ConnStr))
                {
                    using (SqlCommand cmd = new SqlCommand("GetJobByClient", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;

                        cmd.Parameters.AddWithValue("@clientName", clientData.ClientName.ToUpper());
                        cmd.Parameters.AddWithValue("@macAddress", clientData.MacAddress.ToUpper());
                        conn.Open();

                        SqlDataReader reader = cmd.ExecuteReader();

                        ///只可能返回一条记录 所以能用if
                        if (reader.Read() == true)
                        {
                            ret.Imei = reader["Imei"].ToString();
                            ret.Sha = reader["Sha"].ToString();
                            ret.JobId = (int)reader["JobId"];
                            ret.SliceWidth = (int)reader["SliceWidth"];
                            ret.SliceNum = (int)reader["SliceNum"];
                        }
                        else
                        {
                            ///没有返回记录 标记为201 无可用任务
                            ret.ErrorCode = 201;
                        }
                    }
                }
            }
            catch (SqlException ex)
            {

                SaveErrorMessage("\r\nGetJobByClient \r\n" + ex.Message);
            }
            return ret;
        }

        /// <summary>
        /// 设置任务进度，进度为100时设置任务完成，终端其他子任务
        /// </summary>
        /// <param name="clientName"></param>
        /// <param name="macAddress"></param>
        /// <param name="jobId"></param>
        /// <param name="progress"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        internal static bool SetJobProgress(ClientSyncData clientData)
        {
            bool ret = false;

            try
            {
                using (SqlConnection conn = new SqlConnection(ConnStr))
                {
                    using (SqlCommand cmd = new SqlCommand("SetJobProgress", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;

                        cmd.Parameters.AddWithValue("@clientName", clientData.ClientName.ToUpper());
                        cmd.Parameters.AddWithValue("@macAddress", clientData.MacAddress.ToUpper());
                        cmd.Parameters.AddWithValue("jobId", clientData.JobId);
                        cmd.Parameters.AddWithValue("progress", clientData.Progress);
                        cmd.Parameters.AddWithValue("result", clientData.Result);
                        cmd.Parameters.Add("@RetVal", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
                        conn.Open();
                        cmd.ExecuteNonQuery();
                        ret = (int)cmd.Parameters["@RetVal"].Value == 0 ? true : false;
                    }
                }
            }
            catch (SqlException ex)
            {
                SaveErrorMessage("\r\nSetJobProgress \r\n" + ex.Message);
            }

            return ret;

        }

        #endregion

        #region Status
        internal static List<Client> GetClientScore()
        {
            List<Client> ret = new List<Client>();

            try
            {
                using (SqlConnection conn = new SqlConnection(ConnStr))
                {
                    using (SqlCommand cmd = new SqlCommand("GetClientScore", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;

                        conn.Open();
                        SqlDataReader reader = cmd.ExecuteReader();
                        while (reader.Read())
                        {
                            Client client = new Client();

                            client.ClientName = reader["ClientName"].ToString();
                            client.Score = (int)reader["Score"];

                            //client.MacAddress = reader["MacAddress"].ToString();

                            client.LastActive = (DateTime)reader["LastActive"];
                            client.Status = (EnumStatus)reader["StatusId"];
                            ret.Add(client);
                        }
                    }
                }
            }
            catch (SqlException ex)
            {
                SaveErrorMessage("\r\nSetJobProgress \r\n" + ex.Message);
            }

            return ret;

        }

        #endregion



        private static void SaveErrorMessage(string message)
        {
            File.AppendAllText("d:\\log.txt", "\r\n" + DateTime.Now.ToLongTimeString() + "\r\n" + message + "\r\n");
        }


        internal static List<Task> GetHiddenTasks()
        {
            List<Task> tasks = new List<Task>();
            try
            {
                using (SqlConnection conn = new SqlConnection(ConnStr))
                {
                    using (SqlCommand cmd = new SqlCommand("GetHiddenTasks", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        conn.Open();
                        SqlDataReader reader = cmd.ExecuteReader();
                        while (reader.Read())
                        {
                            Task task = new Task
                            {
                                Priority = (int)reader["Priority"],
                                Imei = reader["Imei"].ToString(),
                                StatusId = (int)reader["StatusId"],
                                Memo = reader["Memo"].ToString(),
                                Progress = reader["Progress"].ToString(),
                                Result = reader["Result"].ToString(),
                            };
                            tasks.Add(task);
                        }

                    }
                }
            }
            catch (SqlException ex)
            {
                SaveErrorMessage("\r\nGetAllTasks \r\n" + ex.Message);
            }
            return tasks;
        }
    }
}